package org.wevil.service.sys;

import org.wevil.entity.cond.CondUserRole;
import org.wevil.entity.sys.SysUser;
import org.wevil.params.add.UserAP;
import org.wevil.params.update.UserRoleUP;
import org.wevil.params.update.WxUserUP;
import org.wevil.repo.CondUserRoleRepo;
import org.wevil.repo.sys.SysUserRepo;
import org.wevil.util.BeanUtil;
import org.wevil.vo.detail.UserDetailVo;
import org.wevil.vo.list.MenuListVo;
import org.wevil.vo.list.RoleListVo;
import org.wevil.vo.list.UserListVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
public class UserService {

    @Resource
    private SysUserRepo sysUserRepo;
    @Resource
    private CondUserRoleRepo condUserRoleRepo;
    @Resource
    private RoleService roleService;
    @Resource
    private ResService resService;
    @Resource
    private MenuService menuService;

    /** 创建用户 */
    public void createUser(UserAP param) {
        SysUser user = new SysUser();
        BeanUtil.copyPropIgnoreNull(param, user);
        user.setAvatar("/files/avatar/default.png");
        if(param.getAvatarId() != null){
            String avatar = resService.getById(param.getAvatarId()).getUri();
            user.setAvatar(avatar);
        }
        sysUserRepo.save(user);
    }

    /** 获取用户名 */
    public String getUserName(Integer userId) {
        Optional<SysUser> opt = sysUserRepo.findById(userId);
        return opt.map(SysUser::getUsername).orElse(null);
    }

    /**通过用户名查找用户*/
    public SysUser getUserByUserName(String userName) {
        return sysUserRepo.findByUsername(userName);
    }

    /** 根据用户名和密码查询 */
    public SysUser findByUsernameAndPassword(String username, String password) {
        return sysUserRepo.findByUsernameAndPassword(username, password);
    }

    /** 实体转vo */
    public UserListVo entity2vo(SysUser sysUser) {
        if(sysUser != null){
            UserListVo vo = new UserListVo();
            BeanUtil.copyPropIgnoreNull(sysUser, vo);
            return vo;
        }
        return null;
    }

    /** 批量实体转vo */
    public List<UserListVo> entity2vos(List<SysUser> users) {
        if(users!=null && users.size()>0){
            List<UserListVo> vos = new ArrayList<>();
            for(SysUser sysUser : users){
                vos.add(entity2vo(sysUser));
            }
            return vos;
        }
        return null;
    }

    /** 通过id查找用户 */
    public SysUser findUserById(Integer userId) {
        Optional<SysUser> opt = sysUserRepo.findById(userId);
        return opt.orElse(null);
    }

    /** 获取用户角色id列表 */
    public List<Integer> getRoleIds(Integer userId) {
        return condUserRoleRepo.findRoleIdByUserId(userId);
    }

    /** 获取用户角色名称列表 */
    public List<String> getRoleNames(Integer userId){
        List<Integer> roleIds = condUserRoleRepo.findRoleIdByUserId(userId);
        return roleService.gerRoleNamesByIdIn(roleIds);
    }

    /** 通过用户id查询用户名 */
    public List<String> getUserNamesByUserIds(List<Integer> userIds) {
        return sysUserRepo.findUserNameByIdIn(userIds);
    }

    /** 获取用户详情信息，带角色组织信息 */
    public UserDetailVo getUserDetailVo(Integer userId) {
        Optional<SysUser> optional = sysUserRepo.findById(userId);
        if(optional.isPresent()){
            SysUser sysUser = optional.get();
            UserDetailVo dto = new UserDetailVo();
            BeanUtil.copyPropIgnoreNull(sysUser, dto);
            // 设置用户角色
            List<RoleListVo> roleList = getUserCondRoleList(userId);
            String roleNames = roleList.stream().map(RoleListVo::getName).collect(Collectors.joining(","));
            dto.setRoleNames(roleNames);
            dto.setRoles(roleList);
            // 设置用户菜单
            List<MenuListVo> menus = menuService.getMenuListByUser(userId);
            dto.setMenus(menus);
            return dto;
        }
        return null;
    }

    /** 修改用户密码 */
    public void updatePassword(Integer userId, String pwd) {
        SysUser sysUser = new SysUser();
        sysUser.setId(userId);
        sysUser.setPassword(pwd);
        sysUserRepo.update(sysUser);
    }

    /** 更新微信用户数据 */
    public SysUser updateWxUser(WxUserUP param) {
        SysUser user = sysUserRepo.findByTel(param.getTel());
        if (user == null) { // 用户不存在，创建用户
            // 新建一个空用户
            user = new SysUser();
            user = sysUserRepo.save(user);
            roleService.userCondRole(user.getId(), -1);
        }
        user.setUsername(param.getNickName());
        user.setRealname(param.getNickName());
        user.setAvatar(param.getAvatarUrl());
        user.setTel(param.getTel());
        user.setPassword(param.getTel().substring(7));
        user.setOpenid(param.getOpenid());
        sysUserRepo.update(user);
        return sysUserRepo.findByTel(param.getTel());
    }

    // ------------------------------------用户-角色-----------------------------------------------------------//

    /** 获取用户关联角色 */
    public List<RoleListVo> getUserCondRoleList(Integer userId) {
        List<RoleListVo> vos = new ArrayList<>();
        List<Integer> roleIds = condUserRoleRepo.findRoleIdByUserId(userId);
        if(roleIds!=null && roleIds.size()>0){
            return roleService.getRoleListByIds(roleIds);
        }
        return vos;
    }

    /** 修改用户关联角色 */
    public void updateUserCondRoleList(UserRoleUP param) {
        Integer id = param.getId();
        List<Integer> roleIds = param.getRoleIds();
        condUserRoleRepo.deleteByUserId(id);
        if(roleIds != null && roleIds.size()>0){
            for(Integer roleId : roleIds){
                CondUserRole entity = new CondUserRole();
                entity.setUserId(id);
                entity.setRoleId(roleId);
                condUserRoleRepo.save(entity);
            }
        }
    }
}
